package com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.repository;

import cn.hutool.core.util.StrUtil;
import com.iwhalecloud.citybrain.flow.platform.manager.application.utils.BeanCopierUtils;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.FlowNodeCandidateDomain;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.ModelNextNodeCandidateSettings;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.ModelNextNodeCandidateSettingsDomain;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.FlowNextNodeCandidateRepository;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.entities.FlowNodeCandidateSettings;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.entities.FlowNodeCandidateSettingsExample;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.mapper.FlowNodeCandidateSettingsMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Description 流程下一节点候选人实现方法
 * @author liujinjian
 * @date 2021-10-22
 * @version 1.0
 */
@Repository
public class FlowNextNodeCandidateRepositoryImpl implements FlowNextNodeCandidateRepository {

    @Autowired
    private FlowNodeCandidateSettingsMapper flowNodeCandidateSettingsMapper;

    /**
     * @Descriptiion 删除流程任务下一候选人记录
     * @author liujinjian
     * @date 2021-10-22
     * @param id
     * @return
     */
    @Override
    public int deleteByPrimaryKey(Long id) {
        return flowNodeCandidateSettingsMapper.deleteByPrimaryKey(id);
    }

    /**
     * @Description 插入流程任务下一节点候选者记录
     * @author liujinjian
     * @date 2021-10-22
     * @param record
     * @return
     */
    @Override
    public int insert(ModelNextNodeCandidateSettings record) {
        FlowNodeCandidateSettings entity = new FlowNodeCandidateSettings();
        BeanCopierUtils.copyProperties(record,entity);
        return flowNodeCandidateSettingsMapper.insert(entity);
    }

    /**
     * @Description 插入选中的流程节点负责人记录
     * @author liujinjian
     * @date 2021-10-22
     * @param record
     * @return
     */
    @Override
    public int insertSelective(ModelNextNodeCandidateSettings record) {
        FlowNodeCandidateSettings entity = new FlowNodeCandidateSettings();
        BeanCopierUtils.copyProperties(record,entity);
        return flowNodeCandidateSettingsMapper.insertSelective(entity);
    }

    /**
     * @Description 根据主键查询流程下一节点候选人记录
     * @author liujinjian
     * @date 2021-10-22
     * @param id
     * @return
     */
    @Override
    public ModelNextNodeCandidateSettings selectByPrimaryKey(Long id) {
        ModelNextNodeCandidateSettings entity = new ModelNextNodeCandidateSettings();
        FlowNodeCandidateSettings record = flowNodeCandidateSettingsMapper.selectByPrimaryKey(id);
        BeanCopierUtils.copyProperties(record, entity);
        return entity;
    }

    /**
     * @Description 根据主键更新选中的下一节点候选人记录
     * @author liujinjian
     * @date 2021-10-22
     * @param record
     * @return
     */
    @Override
    public int updateByPrimaryKeySelective(ModelNextNodeCandidateSettings record) {
        FlowNodeCandidateSettings entity = new FlowNodeCandidateSettings();
        BeanCopierUtils.copyProperties(record,entity);
        return flowNodeCandidateSettingsMapper.updateByPrimaryKeySelective(entity);
    }

    /**
     * @Description 根据主键更新候选人信息记录
     * @author liujinjian
     * @date 2021-10-22
     * @param record
     * @return
     */
    @Override
    public int updateByPrimaryKey(ModelNextNodeCandidateSettings record) {
        FlowNodeCandidateSettings entity = new FlowNodeCandidateSettings();
        BeanCopierUtils.copyProperties(record,entity);
        return flowNodeCandidateSettingsMapper.updateByPrimaryKey(entity);
    }

    /**
     * @Description 根据条件获取节点候选人集合列表
     * @author liujinjian
     * @date 2021-10-22
     * @param processInstanceId
     * @param nodeCode
     * @param dataType
     * @return
     */
    @Override
    public List<ModelNextNodeCandidateSettings> selectModelNextNodeCandidateSettings(String processInstanceId, String nodeCode, String dataType) {
        FlowNodeCandidateSettingsExample query = new FlowNodeCandidateSettingsExample();
        FlowNodeCandidateSettingsExample.Criteria criteria = query.createCriteria().andProcessInstanceIdEqualTo(processInstanceId);
        criteria.andNodeCodeEqualTo(nodeCode);
        if (StrUtil.isNotEmpty(dataType)) {
            criteria.andDataTypeEqualTo(dataType);
        }

        List<FlowNodeCandidateSettings> configs = flowNodeCandidateSettingsMapper.selectByExampleWithCriteria(query);

        return configs.stream().map(this::convert).collect(Collectors.toList());
    }

    /**
     * @param modelNextNodeCandidateSettingsDomain
     * @Description 保存节点候选人记录
     * @author liujinjian
     * @date 2021-10-22
     */
    @Override
    public boolean save(ModelNextNodeCandidateSettingsDomain modelNextNodeCandidateSettingsDomain) {
        FlowNodeCandidateSettings entity = new FlowNodeCandidateSettings();
        BeanCopierUtils.copyProperties(modelNextNodeCandidateSettingsDomain,entity);

        return flowNodeCandidateSettingsMapper.insertSelective(entity)>0;
    }

    /**
     * @Description 根据条件获取节点候选人集合列表
     * @author liujinjian
     * @date 2021-10-22
     * @param processInstanceId
     * @param nodeCode
     * @param dataType
     * @return
     */
    @Override
    public List<ModelNextNodeCandidateSettingsDomain> selectModelNextNodeCandidateSettingsDomain(String processInstanceId, String nodeCode, String dataType) {
        FlowNodeCandidateSettingsExample query = new FlowNodeCandidateSettingsExample();
        FlowNodeCandidateSettingsExample.Criteria criteria = query.createCriteria().andProcessInstanceIdEqualTo(processInstanceId);
        if (StrUtil.isNotEmpty(nodeCode)) {
            criteria.andNodeCodeEqualTo(nodeCode);
        }
        if (StrUtil.isNotEmpty(dataType)) {
            criteria.andDataTypeEqualTo(dataType);
        }

        List<FlowNodeCandidateSettings> configs = flowNodeCandidateSettingsMapper.selectByExampleWithCriteria(query);

        return configs.stream().map(this::convertToDoamain).collect(Collectors.toList());
    }

    /**
     * @Description 创建下一节点候选人信息设置记录
     * @author liujinjian
     * @date 2021-10-22
     * @param flowNodeCandidateDomain
     * @return
     */
    @Override
    public int create(FlowNodeCandidateDomain flowNodeCandidateDomain) {
        FlowNodeCandidateSettings entity = new FlowNodeCandidateSettings();
        BeanCopierUtils.copyProperties(flowNodeCandidateDomain,entity);
        return flowNodeCandidateSettingsMapper.insert(entity);
    }

    /**
     * @Description 更新下一节点候选人信息记录
     * @author liujinjian
     * @date 2021-10-22
     * @param flowNodeCandidateDomain
     * @return
     */
    @Override
    public void update(FlowNodeCandidateDomain flowNodeCandidateDomain) {
        FlowNodeCandidateSettings entity = new FlowNodeCandidateSettings();
        BeanCopierUtils.copyProperties(flowNodeCandidateDomain,entity);
        flowNodeCandidateSettingsMapper.updateByPrimaryKeySelective(entity);
    }

    /**
     * @Description 根据流程实例ID和节点编码查询候选人列表信息
     * @author liujinjian
     * @date 2021-10-23
     * @param processInstanceId
     * @param nodeCode
     * @return
     */
    @Override
    public List<ModelNextNodeCandidateSettings> selectByProcessInstanceIdAndNodeCode(String processInstanceId, String nodeCode) {
        FlowNodeCandidateSettingsExample query = new FlowNodeCandidateSettingsExample();
        query.createCriteria().andProcessInstanceIdEqualTo(processInstanceId).andNodeCodeEqualTo(nodeCode);

        List<FlowNodeCandidateSettings> configs = flowNodeCandidateSettingsMapper.selectByExampleWithCriteria(query);

        return configs.stream().map(this::convert).collect(Collectors.toList());
    }

    /**
     * @Description 根据流程实例ID查询候选人列表信息
     * @author cp
     * @date 2022-03-04
     * @param processInstanceId
     * @return
     */
    @Override
    public List<ModelNextNodeCandidateSettings> selectByProcessInstanceId(String processInstanceId) {
        FlowNodeCandidateSettingsExample query = new FlowNodeCandidateSettingsExample();
        query.createCriteria().andProcessInstanceIdEqualTo(processInstanceId);

        List<FlowNodeCandidateSettings> configs = flowNodeCandidateSettingsMapper.selectByExampleWithCriteria(query);

        return configs.stream().map(this::convert).collect(Collectors.toList());
    }


    /**
     * @Description 根据流程实例ID和来源节点编码查询候选人列表信息
     * @author cp
     * @date 2022-03-02
     * @param processInstanceId
     * @param fromNodeCode
     * @return
     */
    @Override
    public List<ModelNextNodeCandidateSettings> selectByProcessInstanceIdAndFromNodeCode(String processInstanceId, String fromNodeCode) {
        FlowNodeCandidateSettingsExample query = new FlowNodeCandidateSettingsExample();
        query.createCriteria().andProcessInstanceIdEqualTo(processInstanceId).andFromNodeCodeEqualTo(fromNodeCode);

        List<FlowNodeCandidateSettings> configs = flowNodeCandidateSettingsMapper.selectByExampleWithCriteria(query);

        return configs.stream().map(this::convert).collect(Collectors.toList());
    }

    @Override
    public List<ModelNextNodeCandidateSettings> selectByProcessInstanceIdAndNodeCodeAndParentExecutionId(String processInstanceId, String nodeCode, String parentExecutionId) {
        FlowNodeCandidateSettingsExample query = new FlowNodeCandidateSettingsExample();
        FlowNodeCandidateSettingsExample.Criteria criteria = query.createCriteria();
        criteria.andProcessInstanceIdEqualTo(processInstanceId).andNodeCodeEqualTo(nodeCode);
        if (StringUtils.isNotBlank(parentExecutionId)){
            criteria.andParentExecutionIdEqualTo(parentExecutionId);
        }

        List<FlowNodeCandidateSettings> configs = flowNodeCandidateSettingsMapper.selectByExampleWithCriteria(query);

        return configs.stream().map(this::convert).collect(Collectors.toList());
    }

    /**
     * @Description 根据条件获取节点候选人集合列表
     * @author liujinjian
     * @date 2021-10-22
     * @param processInstanceId
     * @param nodeCode
     * @param dataType
     * @param code
     * @return
     */
    @Override
    public List<ModelNextNodeCandidateSettingsDomain> selectModelCandidateSettingsDomain(String processInstanceId, String nodeCode, String dataType, String code) {
        FlowNodeCandidateSettingsExample query = new FlowNodeCandidateSettingsExample();
        FlowNodeCandidateSettingsExample.Criteria criteria = query.createCriteria().andProcessInstanceIdEqualTo(processInstanceId);
        criteria.andNodeCodeEqualTo(nodeCode);
        if (StrUtil.isNotEmpty(dataType)) {
            criteria.andDataTypeEqualTo(dataType);
        }
        if (StrUtil.isNotEmpty(code)) {
            criteria.andCodeEqualTo(code);
        }

        List<FlowNodeCandidateSettings> configs = flowNodeCandidateSettingsMapper.selectByExampleWithCriteria(query);

        return configs.stream().map(this::convertToDoamain).collect(Collectors.toList());
    }

    private ModelNextNodeCandidateSettings convert(FlowNodeCandidateSettings record) {
        if (Objects.isNull(record)) {
            return null;
        }
        ModelNextNodeCandidateSettings config = new ModelNextNodeCandidateSettings();
        BeanCopierUtils.copyProperties(record, config);
        return config;
    }

    private ModelNextNodeCandidateSettingsDomain convertToDoamain(FlowNodeCandidateSettings record){
        if (Objects.isNull(record)) {
            return null;
        }
        ModelNextNodeCandidateSettingsDomain config = new ModelNextNodeCandidateSettingsDomain();
        BeanCopierUtils.copyProperties(record, config);
        return config;
    }
}